﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BusinessLogic;
using BusinessObjects;
using DCMS_Framework;

namespace Presentation.Children {
  /// <summary>
  /// Parentfiche for child
  /// </summary>
  public partial class ParentFicheControl : UserControl {

    private ZipcodeBll zipcodeBll;
    private SortableBindingList<CityZipcode> zipcodeList;
    private FormType type;
    private BindingSource controlBindingSource;
    private Child currentChild;

    #region - Properties -

    /// <summary>
    /// Gets or sets the current child.
    /// </summary>
    /// <value>
    /// The current child.
    /// </value>
    public Child CurrentChild {
      get { return currentChild; }
      set { currentChild = value; }
    }

    /// <summary>
    /// Gets or sets the zipcode list.
    /// </summary>
    /// <value>
    /// The zipcode list.
    /// </value>
    public SortableBindingList<CityZipcode> ZipcodeList {
      get { return zipcodeList; }
      set { zipcodeList = value; }
    }

    /// <summary>
    /// Gets or sets the type.
    /// </summary>
    /// <value>
    /// The type.
    /// </value>
    public FormType Type {
      get { return type; }
      set {
        type = value;
        switch ( type ) {
          case FormType.Mother:
            groupBoxName.Text = "Moeder";
            groupBoxEmployee.Visible = true;
            break;
          case FormType.Father:
            groupBoxName.Text = "Vader";
            groupBoxEmployee.Visible = true;
            break;
          default:
            groupBoxEmployee.Visible = true;
            break;
        }
      }
    }

    /// <summary>
    /// Gets or sets the control binding source.
    /// </summary>
    /// <value>
    /// The control binding source.
    /// </value>
    public BindingSource ControlBindingSource {
      get { return controlBindingSource; }
      set { controlBindingSource = value; }
    }

    #endregion

    #region - Constructor -

    /// <summary>
    /// Initializes a new instance of the <see cref="ParentFicheControl"/> class.
    /// </summary>
    public ParentFicheControl( ) {
      InitializeComponent( );
      controlBindingSource = new BindingSource( );
      currentChild = new Child( );
      zipcodeBll = new ZipcodeBll( );
      controlBindingSource.DataSource = typeof( BusinessObjects.Child );
      openPictureFileDialog.Filter = "jpg files (*.jpg)|*.jpg|png files (*.png)|*.png|bmp files|*.bmp|All files (*.*)|*.*";
    }

    #endregion

    #region - Events -

    private void ParentFicheControl_Load( object sender, EventArgs e ) {

      SetDataBinding( );

      if ( CurrentChild != null ) {
        switch ( this.Type ) {
          case FormType.Mother:
            pictureCloseButton.Visible = ( CurrentChild.Mother.Photo != null );
            break;
          case FormType.Father:
            pictureCloseButton.Visible = ( CurrentChild.Father.Photo != null );
            break;
          default:
            break;
        }
        zipcodeList = zipcodeBll.GetAllZipcodes( );
      }
    }

    private void searchZipcodeButton_Click( object sender, EventArgs e ) {
      ZipcodeListForm zipcodeForm = new ZipcodeListForm( );
      if ( zipcodeForm.ShowDialog( ) == DialogResult.OK ) {
        this.zipcodeTextBox.Text = zipcodeForm.Zipcode.Zipcode;
        this.cityTextBox.Text = zipcodeForm.Zipcode.City;
        SetParentCityZipcode( zipcodeForm.Zipcode );

      }
    }

    private void employerSearchZipcodeButton_Click( object sender, EventArgs e ) {
      ZipcodeListForm zipcodeForm = new ZipcodeListForm( );
      if ( zipcodeForm.ShowDialog( ) == DialogResult.OK ) {
        this.employerCityTextBox.Text = zipcodeForm.Zipcode.City;
        this.employerZipcodeTextBox.Text = zipcodeForm.Zipcode.Zipcode;
        SetEmployerCityZipcode( zipcodeForm.Zipcode );
      }
    }

    private void zipcodeTextBox_Leave( object sender, EventArgs e ) {
      bool found = false;
      if ( !string.IsNullOrEmpty( zipcodeTextBox.Text ) ) {
        foreach ( CityZipcode zipcode in zipcodeList ) {
          if ( zipcode.Zipcode == zipcodeTextBox.Text ) {
            SetParentCityZipcode( zipcode );
            found = true;
            break;
          }
        }
        if ( !found ) {
          SetParentCityZipcode( null );
        }
      }
    }

    private void employerZipcodeTextBox_Leave( object sender, EventArgs e ) {
      bool found = false;
      if ( !string.IsNullOrEmpty( employerZipcodeTextBox.Text ) ) {
        foreach ( CityZipcode zipcode in zipcodeList ) {
          if ( zipcode.Zipcode == employerZipcodeTextBox.Text ) {
            SetEmployerCityZipcode( zipcode );
            found = true;
            break;
          }
        }
        if ( !found ) {
          SetEmployerCityZipcode( null );
        }
      }
    }

    private void pictureCloseButton_Click( object sender, EventArgs e ) {
      if ( MessageBox.Show( "Foto verwijderen?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question ) == DialogResult.Yes ) {
        switch ( this.Type ) {
          case FormType.Mother:
            currentChild.Mother.Photo = null;
            photoPictureBox.Image = null;
            pictureCloseButton.Visible = false;
            break;
          case FormType.Father:
            currentChild.Father.Photo = null;
            photoPictureBox.Image = null;
            pictureCloseButton.Visible = false;
            break;
          default:
            break;
        }
      }
    }

    private void photoButton_Click( object sender, EventArgs e ) {
      if ( openPictureFileDialog.ShowDialog( ) == DialogResult.OK ) {
        Image photo = Image.FromFile( openPictureFileDialog.FileName );
        switch ( this.Type ) {
          case FormType.Mother:
            CurrentChild.Mother.Photo = photo;
            break;
          case FormType.Father:
            CurrentChild.Father.Photo = photo;
            break;
          default:
            break;
        }
        this.photoPictureBox.Image = photo;
      }
    }

    private void photoPictureBox_BindingContextChanged( object sender, EventArgs e ) {
      if ( currentChild != null ) {

        switch ( this.Type ) {
          case FormType.Mother:
            pictureCloseButton.Visible = ( CurrentChild.Mother.Photo != null );
            break;
          case FormType.Father:
            pictureCloseButton.Visible = ( CurrentChild.Father.Photo != null );
            break;
          default:
            break;
        }
      }
    }

    private void textBox_TextChanged( object sender, EventArgs e ) {
      parentErrorProvider.SetError( ( Control ) sender, "" );
    }

    private void readIdCardButton_Click( object sender, EventArgs e ) {
      try {
        BasicCardData data = CardReader.ReadCard( );
        if ( data != null ) {
          nameTextBox.Text = data.Name;
          firstNameTextBox.Text = data.FirstName;
          streetTextBox.Text = data.Street;
          zipcodeTextBox.Text = data.Zipcode;
          cityTextBox.Text = data.City;
          bool zipcodeExists = false;
          foreach ( CityZipcode zipcode in zipcodeList ) {
            if ( zipcode.Zipcode == data.Zipcode
              && zipcode.City == data.City
              && zipcode.CountryCode == data.CountryCode ) {
              zipcodeExists = true;
            }
          }
          if ( !zipcodeExists ) {
            CityZipcode zip = new CityZipcode( data.Zipcode, data.City, data.CountryId );
            zip.ZipcodeId = 0;
            zipcodeBll.SaveZipcode( zip );
          }
          photoPictureBox.Image = data.Photo;
          photoPictureBox.Visible = true;
          nationalNumberTextBox.Text = data.NationalNumber;
          if ( CurrentChild != null ) {
            switch ( this.Type ) {
              case FormType.Mother:
                CurrentChild.Mother.Photo = data.Photo;
                break;
              case FormType.Father:
                CurrentChild.Father.Photo = data.Photo;
                break;
              default:
                break;
            }
            
          }
        }

      } catch ( be.belgium.eid.BEID_ExNoReader ) {
        MessageBox.Show( "Geen kaartlezer gevonden. \n Controleer of deze goed is aangesloten en probeer opnieuw", "Kaartlezer", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
      } catch ( be.belgium.eid.BEID_ExNoCardPresent ) {
        MessageBox.Show( "Geen kaart gevonden.", "Kaartlezer", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
      } catch ( Exception ex ) {
        MessageBox.Show( ex.ToString( ) + "\n" + ex.Message, "Kaartlezer fout", MessageBoxButtons.OK, MessageBoxIcon.Error );
      }

    }

    private void selectText_MouseDown( object sender, MouseEventArgs e ) {
      ( ( TextBox ) sender ).SelectAll( );
    }

    #endregion

    #region - Private Methods -

    private void SetParentCityZipcode( CityZipcode zipcode ) {
      switch ( this.Type ) {
        case FormType.Mother:
          SetZipcode( currentChild.Mother.Address, zipcode );
          break;
        case FormType.Father:
          SetZipcode( currentChild.Father.Address, zipcode );
          break;
        default:
          break;
      }
    }

    private void SetEmployerCityZipcode( CityZipcode zipcode ) {
      switch ( this.Type ) {
        case FormType.Mother:
          SetZipcode( currentChild.Mother.Employer.Address, zipcode );
          break;
        case FormType.Father:
          SetZipcode( currentChild.Father.Employer.Address, zipcode );
          break;
        default:
          break;
      }
    }

    private void SetZipcode( Address address, CityZipcode zipcode ) {
      if ( zipcode == null ) {
        address.City = string.Empty;
        address.Zipcode = string.Empty;
        address.ZipcodeId = 0;
        address.CountryName = string.Empty;
        address.CountryCode = Country.DefaultCountryCode;
        address.CountryId = Country.DefaultCountryId;
      } else {
        address.City = zipcode.City;
        address.Zipcode = zipcode.Zipcode;
        address.ZipcodeId = zipcode.ZipcodeId;
        address.CountryName = zipcode.CountryName;
        address.CountryCode = zipcode.CountryCode;
        address.CountryId = zipcode.CountryId;
      }
    }

    private void SetDataBinding( ) {
      switch ( this.type ) {
        case FormType.Mother:
          this.nameTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.Name", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.firstNameTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.FirstName", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.phoneTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.Phone", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.gsmTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.Gsm", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.emailTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.Email", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.nationalNumberTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.NationalNumber", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.photoPictureBox.DataBindings.Add( new Binding( "Image", this.ControlBindingSource, "Mother.Photo", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.streetTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.Address.Street", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.zipcodeTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.Address.Zipcode", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.cityTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.Address.City", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.employerNameTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.Employer.Name", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.employerPhoneTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.Employer.Phone", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.employerStreetTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.Employer.Address.Street", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.employerZipcodeTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.Employer.Address.Zipcode", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.employerCityTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Mother.Employer.Address.City", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.mainAddressCheckBox.DataBindings.Add( new Binding( "Checked", this.ControlBindingSource, "Mother.MainAddress", true, DataSourceUpdateMode.OnPropertyChanged ) );
          break;
        case FormType.Father:
          this.nameTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.Name", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.firstNameTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.FirstName", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.phoneTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.Phone", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.gsmTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.Gsm", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.emailTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.Email", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.nationalNumberTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.NationalNumber", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.photoPictureBox.DataBindings.Add( new Binding( "Image", this.ControlBindingSource, "Father.Photo", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.streetTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.Address.Street", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.zipcodeTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.Address.Zipcode", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.cityTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.Address.City", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.employerNameTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.Employer.Name", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.employerPhoneTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.Employer.Phone", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.employerStreetTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.Employer.Address.Street", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.employerZipcodeTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.Employer.Address.Zipcode", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.employerCityTextBox.DataBindings.Add( new Binding( "Text", this.ControlBindingSource, "Father.Employer.Address.City", true, DataSourceUpdateMode.OnPropertyChanged ) );
          this.mainAddressCheckBox.DataBindings.Add( new Binding( "Checked", this.ControlBindingSource, "Father.MainAddress", true, DataSourceUpdateMode.OnPropertyChanged ) );
          break;
        default:
          break;
      }
    }

    #endregion

    #region - Enums -

    public enum FormType : byte {
      Mother,
      Father
    }

    #endregion

    #region - Validation -

    private void nameTextBox_Validating( object sender, CancelEventArgs e ) {
      parentErrorProvider.SetError( nameTextBox, "" );
      if ( mainAddressCheckBox.Checked ) {
        if ( string.IsNullOrEmpty( nameTextBox.Text ) ) {
          parentErrorProvider.SetIconAlignment( nameTextBox, ErrorIconAlignment.MiddleLeft );
          parentErrorProvider.SetError( nameTextBox, "Naam verplicht" );
          e.Cancel = true;
        }
      }
    }

    private void phoneTextBox_Validating( object sender, CancelEventArgs e ) {
      parentErrorProvider.SetError( phoneTextBox, "" );
      parentErrorProvider.SetError( gsmTextBox, "" );
      if ( this.Type == FormType.Mother ) {

        if ( string.IsNullOrEmpty( phoneTextBox.Text ) && string.IsNullOrEmpty( gsmTextBox.Text ) ) {
          parentErrorProvider.SetIconAlignment( phoneTextBox, ErrorIconAlignment.MiddleLeft );
          parentErrorProvider.SetError( phoneTextBox, "Minstens 1 contactnummer nodig." );
          e.Cancel = true;
        }
      }
    }

    private void streetTextBox_Validating( object sender, CancelEventArgs e ) {
      parentErrorProvider.SetError( streetTextBox, "" );
      if ( mainAddressCheckBox.Checked ) {
        if ( string.IsNullOrEmpty( streetTextBox.Text ) ) {
          parentErrorProvider.SetError( streetTextBox, "Adres verplicht." );
          e.Cancel = true;
        }
      }
    }

    private void zipcodeTextBox_Validating( object sender, CancelEventArgs e ) {
      parentErrorProvider.SetError( zipcodeTextBox, "" );
      if ( mainAddressCheckBox.Checked ) {
        if ( string.IsNullOrEmpty( zipcodeTextBox.Text ) ) {
          parentErrorProvider.SetError( zipcodeTextBox, "Adres verplicht." );
          e.Cancel = true;
        }
      }
    }

    private void emailTextBox_Validating( object sender, CancelEventArgs e ) {
      parentErrorProvider.SetError( emailTextBox, "" );
      if ( !string.IsNullOrEmpty( emailTextBox.Text ) ) {
        if ( !PresentationHelper.VaildateEmailString( emailTextBox.Text ) ) {
          parentErrorProvider.SetError( emailTextBox, "Ongeldig formaat." );
          e.Cancel = true;
        }
      }
    }

    private void control_Validated( object sender, EventArgs e ) {
      parentErrorProvider.SetError( ( Control ) sender, "" );
    }

    #endregion
    
  }
}
